home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -in_the_mag- / reader_requests / amiga-e / examples / dragndrop.e < prev    next >
Text File  |  1999-09-13  |  12KB  |  333 lines

  1. /*
  2. **  Original C Code written by Stefan Stuntz
  3. **
  4. **  Translation into E by Klaus Becker
  5. **
  6. **  All comments are from the C-Source
  7. */
  8.  
  9. OPT PREPROCESS
  10.  
  11. MODULE 'muimaster','libraries/mui','libraries/muip',
  12.        'mui/muicustomclass','amigalib/boopsi',
  13.        'intuition/classes','intuition/classusr',
  14.        'intuition/screens','intuition/intuition',
  15.        'utility/tagitem'
  16.  
  17. DEF nase,fields
  18.  
  19. DEF cl_fieldslist   =NIL: PTR TO mui_customclass
  20. DEF cl_choosefields =NIL: PTR TO mui_customclass
  21.  
  22. OBJECT fieldslist_data
  23.   dummy
  24. ENDOBJECT
  25.  
  26. OBJECT choosefields_data
  27.   dummy
  28. ENDOBJECT
  29.  
  30. PROC doSuperNew(cl:PTR TO iclass,obj,tag1:PTR TO LONG)
  31. ENDPROC doSuperMethodA(cl,obj,[OM_NEW,tag1,NIL])
  32.  
  33. /****************************************************************************/
  34. /* FieldsList class                                                         */
  35. /****************************************************************************/
  36.  
  37. /*
  38. ** FieldsList list class creates a list that accepts D&D items
  39. ** from exactly one other listview, the one which is stored in
  40. ** the objects userdata. You could also store the allowed source
  41. ** object in another private attribute, I was just too lazy to add
  42. ** the get/set methods in this case. :-)
  43. **
  44. ** This class is designed to be used for both, the list of the
  45. ** available fields and the list of the visible fields.
  46. **
  47. ** Note: Stop being afraid of custom classes. This one here takes
  48. ** just a few lines of code, 90% of the stuff below is comments. :-)
  49. */
  50.  
  51. PROC fieldslist_dragquery(cl:PTR TO iclass,obj:PTR TO object,msg:PTR TO muip_dragdrop)
  52.  
  53.   IF (msg.obj=obj)
  54.     /*
  55.     ** If somebody tried to drag ourselves onto ourselves, we let our superclass
  56.     ** (the list class) handle the necessary actions. Depending on the state of
  57.     ** its MUIA_List_DragSortable attribute, it will either accept or refuse to become
  58.     ** the destination object.
  59.     */
  60.     RETURN (doSuperMethodA(cl,obj,msg))
  61.   ELSEIF (msg.obj= muiUserData(obj))
  62.     /*
  63.     ** If our predefined source object wants us to become active,
  64.     ** we politely accept it.
  65.     */
  66.     RETURN (MUIV_DragQuery_Accept)
  67.   ELSE
  68.     /*
  69.     ** Otherwise, someone tried to feed us with something we don't like
  70.     ** very much. Just refuse it.
  71.     */
  72.     RETURN (MUIV_DragQuery_Refuse)
  73.   ENDIF
  74. ENDPROC
  75.  
  76. PROC fieldslist_dragdrop(cl:PTR TO iclass,obj,msg:PTR TO muip_dragdrop)
  77.   DEF entry,dropmark,sortable
  78.  
  79.   IF (msg.obj=obj)
  80.     /*
  81.     ** user wants to move entries within our object, these kinds of actions
  82.     ** can get quite complicated, but fortunately, everything is automatically
  83.     ** handled by list class. We just need to pass through the method.
  84.     */
  85.     RETURN (doSuperMethodA(cl,obj,msg))
  86.   ELSE
  87.     /*
  88.     ** we can be sure that msg->obj is our predefined source object
  89.     ** since we wouldnt have accepted the MUIM_DragQuery and wouldnt
  90.     ** have become an active destination object otherwise.
  91.     */
  92.  
  93.     /*
  94.     ** get the current entry from the source object, remove it there, and insert
  95.     ** it to ourselves. You would have to do a little more action if the source
  96.     ** listview would support multi select, but this one doesnt, so things get
  97.     ** quite easy. Note that this direct removing/adding of list entries is only
  98.     ** possible if both contain lists simple pointers to static items. If they would
  99.     ** feature custom construct/destruct hooks, we'd need to create a copy of
  100.     ** the entries instead of simply moving pointers.
  101.     */
  102.  
  103.     /* get source entry */
  104.     doMethodA(msg.obj,[MUIM_List_GetEntry,MUIV_List_GetEntry_Active,{entry}])
  105.  
  106.     /* remove source entry */
  107.     doMethodA(msg.obj,[MUIM_List_Remove,MUIV_List_Remove_Active])
  108.  
  109.     get(obj,MUIA_List_DragSortable,{sortable})
  110.     IF (sortable)
  111.       /*
  112.       ** if we are in a sortable list (in our case the visible fields),
  113.       ** we need to make sure to insert the new entry at the correct
  114.       ** position. The MUIA_List_DropMark attribute is maintained
  115.       ** by list class and shows us where we shall go after a drop.
  116.       */
  117.  
  118.       get(obj,MUIA_List_DropMark,{dropmark})
  119.       doMethodA(obj,[MUIM_List_InsertSingle,entry,dropmark])
  120.     ELSE
  121.       /*
  122.       ** we are about to return something to the available fields
  123.       ** listview which is always sorted.
  124.       */
  125.       doMethodA(obj,[MUIM_List_InsertSingle,entry,MUIV_List_Insert_Sorted])
  126.     ENDIF
  127.  
  128.     /*
  129.     ** make the insterted object the active and make the source listviews
  130.     ** active object inactive to give some more visual feedback to the user.
  131.     */
  132.  
  133.     get(obj,MUIA_List_InsertPosition,{dropmark})
  134.     set(obj,MUIA_List_Active,dropmark)
  135.     set(msg.obj,MUIA_List_Active,MUIV_List_Active_Off)
  136.   ENDIF
  137. ENDPROC 0
  138.  
  139. PROC fieldslist_dispatcher(cl:PTR TO iclass,obj,msg:PTR TO msg)
  140.   DEF methodid
  141.   methodid:=msg.methodid
  142.   SELECT methodid
  143.     CASE MUIM_DragQuery; RETURN (fieldslist_dragquery(cl,obj,msg))
  144.     CASE MUIM_DragDrop ; RETURN (fieldslist_dragdrop (cl,obj,msg))
  145.    ENDSELECT
  146. ENDPROC (doSuperMethodA(cl,obj,msg))
  147.  
  148. /****************************************************************************/
  149. /* ChooseFields class                                                       */
  150. /****************************************************************************/
  151.  
  152. /*
  153. ** This class creates two listviews, one contains all available fields,
  154. ** the other one contains the visible fields. You can control this
  155. ** stuff completely with D&D. This thing could e.g. be useful to
  156. ** configure the display of an address utility.
  157. */
  158.  
  159. PROC choosefields_new(cl:PTR TO iclass,obj,msg:PTR TO opset)
  160.   DEF available, visible
  161.   obj:= doSuperNew(cl,obj,
  162.     [MUIA_Group_Columns, 2,
  163.     MUIA_Group_VertSpacing, 1,
  164.     Child, TextObject, MUIA_Text_Contents, '\ecAvailable Fields\n(alpha sorted)', End,
  165.     Child, TextObject, MUIA_Text_Contents, '\ecVisible Fields\n(sortable)', End,
  166.     Child, ListviewObject,
  167.       MUIA_Listview_DragType, 1,
  168.       MUIA_Listview_List, available:= NewObjectA(cl_fieldslist.mcc_class,NIL,
  169.         [InputListFrame,
  170.         MUIA_List_SourceArray, fields,
  171.         MUIA_List_ShowDropMarks, FALSE,
  172.         TAG_DONE]),
  173.     End,
  174.     Child, ListviewObject,
  175.       MUIA_Listview_DragType, 1,
  176.       MUIA_Listview_List, visible:= NewObjectA(cl_fieldslist.mcc_class,NIL,
  177.         [InputListFrame,
  178.         MUIA_List_DragSortable, MUI_TRUE,
  179.         TAG_DONE]),
  180.     End,
  181.     TAG_DONE])
  182.  
  183.   IF (obj)
  184.     /*
  185.     ** tell available object to accept items from visible object.
  186.     ** the use of MUIA_UserData is just to make the FieldsList
  187.     ** subclass more simple.
  188.     */
  189.  
  190.     set(available,MUIA_UserData,visible)
  191.  
  192.     /*
  193.     ** the other way round...
  194.     */
  195.  
  196.     set(visible,MUIA_UserData,available)
  197.   ENDIF
  198.  
  199. ENDPROC obj
  200.  
  201. PROC choosefields_dispatcher(cl:PTR TO iclass,obj,msg:PTR TO msg)
  202.   DEF methodid
  203.   methodid:=msg.methodid
  204.   SELECT methodid
  205.     CASE OM_NEW; RETURN (choosefields_new(cl,obj,msg))
  206.   ENDSELECT
  207. ENDPROC (doSuperMethodA(cl,obj,msg))
  208.  
  209. /****************************************************************************/
  210. /* Main Program                                                             */
  211. /****************************************************************************/
  212.  
  213. PROC exitclasses()
  214.   IF (cl_fieldslist  ) THEN Mui_DeleteCustomClass(cl_fieldslist  )
  215.   IF (cl_choosefields) THEN Mui_DeleteCustomClass(cl_choosefields)
  216. ENDPROC
  217.  
  218. PROC initclasses()
  219.   cl_fieldslist    := eMui_CreateCustomClass(NIL,MUIC_List ,NIL,SIZEOF fieldslist_data,{fieldslist_dispatcher})
  220.   cl_choosefields  := eMui_CreateCustomClass(NIL,MUIC_Group,NIL,SIZEOF choosefields_data,{choosefields_dispatcher})
  221.  
  222.   IF (cl_fieldslist AND cl_choosefields) THEN RETURN TRUE
  223.   exitclasses()
  224. ENDPROC FALSE
  225.  
  226. PROC main() HANDLE
  227.   DEF app,window,sigs=0
  228.  
  229.   nase:=['Line 1','Line 2','Line 3','Line 4','Line 5',
  230.          'Line 6','Line 7','Line 8','Line 9','Line 10',
  231.          'Line 11','Line 12','Line 13','Line 14','Line 15',
  232.          'Line 16','Line 17','Line 18','Line 19','Line 20',
  233.          'Line 21','Line 22','Line 23','Line 24','Line 25',
  234.          'Line 26','Line 27','Line 28','Line 29','Line 30',
  235.          'Line 31','Line 32','Line 33','Line 34','Line 35',
  236.          'Line 36','Line 37','Line 38','Line 39','Line 40',
  237.          'Line 41','Line 42','Line 43','Line 44','Line 45',
  238.          'Line 46','Line 47','Line 48','Line 49','Line 50',NIL]
  239.  
  240.   fields:=['Age',
  241.            'Birthday',
  242.            'c/o',
  243.            'City',
  244.            'Comment',
  245.            'Country',
  246.            'EMail',
  247.            'Fax',
  248.            'First name',
  249.            'Job',
  250.            'Name',
  251.            'Phone',
  252.            'Projects',
  253.            'Salutation',
  254.            'State',
  255.            'Street',
  256.            'ZIP',
  257.            NIL]
  258.   
  259.   IF (muimasterbase:=OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))=NIL THEN
  260.     Raise('Failed to open muimaster.library')
  261.  
  262.   IF initclasses()=NIL THEN
  263.     Raise('failed to init classes.')
  264.  
  265.   app:= ApplicationObject,
  266.     MUIA_Application_Title      , 'DragnDrop',
  267.     MUIA_Application_Version    , '$VER: DragnDrop 12.9 (21.11.95)',
  268.     MUIA_Application_Copyright  , 'c1992-95, Stefan Stuntz',
  269.     MUIA_Application_Author     , 'Stefan Stuntz & Klaus Becker',
  270.     MUIA_Application_Description, 'Demonstrate Drag & Drop capabilities',
  271.     MUIA_Application_Base       , 'DRAGNDROP',
  272.     SubWindow, window:= WindowObject,
  273.       MUIA_Window_Title, 'Drag&Drop Demo',
  274.       MUIA_Window_ID   , "DRAG",
  275.       WindowContents, VGroup,
  276.         Child, NewObjectA(cl_choosefields.mcc_class,NIL,[TAG_DONE]),
  277.         Child, ColGroup(2),
  278.           Child, TextObject, TextFrame, MUIA_Background, MUII_TextBack, MUIA_Text_Contents, '\ecListview without\nmultiple selection.', End,
  279.           Child, TextObject, TextFrame, MUIA_Background, MUII_TextBack, MUIA_Text_Contents, '\ecListview with\nmultiple selection.', End,
  280.           Child, ListviewObject,
  281.             MUIA_Listview_DragType, 1,
  282.             MUIA_Dropable, FALSE,
  283.             MUIA_Listview_List, ListObject,
  284.               InputListFrame,
  285.               MUIA_List_SourceArray, nase,
  286.               MUIA_List_DragSortable, MUI_TRUE,
  287.             End,
  288.           End,
  289.           Child, ListviewObject,
  290.             MUIA_Dropable, MUI_TRUE,
  291.             MUIA_Listview_DragType, 1,
  292.             MUIA_Listview_MultiSelect, MUI_TRUE,
  293.             MUIA_Listview_List, ListObject,
  294.               InputListFrame,
  295.               MUIA_List_SourceArray, nase,
  296.               MUIA_List_DragSortable, MUI_TRUE,
  297.             End,
  298.           End,
  299.         End,
  300.       End,
  301.     End,
  302.   End
  303.  
  304.   IF app=NIL THEN
  305.     Raise('Failed to create Application.')
  306.  
  307.   doMethodA(window,[MUIM_Notify,MUIA_Window_CloseRequest,MUI_TRUE,
  308.     app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit])
  309.  
  310.   /*
  311.   ** This is the ideal input loop for an object oriented MUI application.
  312.   ** Everything is encapsulated in classes, no return ids need to be used,
  313.   ** we just check if the program shall terminate.
  314.   ** Note that MUIM_Application_NewInput expects sigs to contain the result
  315.   ** from Wait() (or 0). This makes the input loop significantly faster.
  316.   */
  317.  
  318.   set(window,MUIA_Window_Open,MUI_TRUE)
  319.   
  320.   WHILE (doMethodA(app,[MUIM_Application_NewInput,{sigs}]) <> MUIV_Application_ReturnID_Quit)
  321.     IF (sigs) THEN sigs:=Wait(sigs)
  322.   ENDWHILE
  323.  
  324.   set(window,MUIA_Window_Open,FALSE)
  325.  
  326. EXCEPT DO
  327.  
  328.   IF app THEN Mui_DisposeObject(app) -> note that you must first dispose all objects 
  329.   exitclasses()                      -> *before* deleting the classes! 
  330.   IF muimasterbase THEN CloseLibrary(muimasterbase)
  331.   IF exception THEN WriteF('\s\n',exception)
  332. ENDPROC
  333.